Conversation
0.10.3 stops one version short of the current specification: 0.10.3: PRICING2YAML_VERSIONS = ["1.0","1.1","2.0","2.1","3.0"] 0.11.1: PRICING2YAML_VERSIONS = ["1.0","1.1","2.0","2.1","3.0","3.1"] so registering a pricing written against 3.1 is refused with "Unsupported version: 3.1", and the only way to register anything is to declare 3.0 and stay a version behind. No source change was needed: the imports SPACE uses - retrievePricingFromPath, retrievePricingFromText, and the Pricing/Plan/Feature/UsageLimit types - kept their signatures across the two releases. tsc passes and the API suite passes against a local MongoDB and Redis.
Authentication reads the database, so anything that can go wrong with the
database surfaces as an exception in the auth middleware - and the catch turned
every one of them into 401 with the driver's message as the body:
401 {"error":"connect ECONNREFUSED 127.0.0.1:27017"}
401 {"error":"Operation `users.findOne()` buffering timed out after 10000ms"}
The status says the caller sent a bad key. It sends whoever is debugging to
look at credentials that were never judged, because the request never got far
enough to judge them.
The healthcheck agreed: it returned 200 unconditionally, proving only that the
HTTP listener was up. A SPACE whose MongoDB container had stopped reported
healthy for fifteen hours while refusing every authenticated request as
unauthorised. Two signals agreeing on the wrong answer is what made this
expensive.
authenticateUserApiKey and authenticateOrgApiKey now throw a typed
InvalidApiKeyError for the two cases that really are bad credentials. The catch
answers 401 only for those; anything else is 503 with Retry-After, since the
credential was never judged and the caller should try again.
The healthcheck reports 503 when Mongoose is not connected, and pings the
database when it is - readyState is what the driver believes, a ping is what
the database says, and they disagree when a connection has gone stale.
Verified by stopping the database under a running server:
main: healthcheck 200, authed call 401 {"error":"connect ECONNREFUSED…"}
this PR: healthcheck 503 {"database":"disconnected"}
authed call 503 {"error":"Space cannot verify credentials right now."}
An evaluation that touches two usage limits recorded one of them. _applyExpectedConsumption reads the whole contract, increments a single usage level in its own copy, and writes the whole contract back. evaluateFeature called it once per limit through Promise.all, so every call read the same starting state and only the last write survived - a lost update, silent, on the path that decides whether somebody may use a feature. _applyExpectedConsumptions applies every limit to one contract copy and writes once: correct, and one round trip instead of one per limit. Limits are all validated before anything is written, so naming a limit that does not exist cannot leave the others half-applied. The single-limit method stays, delegating. Seven tests against stubbed repository and cache, including one that pins why the batch method exists: calling the single-limit method concurrently is still lossy, because read-modify-write on a whole document cannot be made safe by calling it more carefully. Making that safe means an atomic $inc in the repository, which is a larger change than this one. Their feature-evaluation suite (26 tests) passes unchanged.
Two falsy checks treated a numeric zero as an absent value, so a caller who named a limit and declared it costs nothing was told they had not named it at all. The same check on the sum also refused an ordinary positive consumption whenever the usage level was still zero, which is the state of every contract on its first call and after every renewal.
The job reads the Mongo port and database name from the `testing` environment, which GitHub withholds from fork pull requests. Both resolved to an empty string, so the action was asked to publish port `` and gave docker `-p :`, which it rejects before any test runs. Defaults now stand in when the environment is absent. They are the only values that can work, since MONGO_URI already hard-codes 27017 and space_testing_db.
Narrowing the catch to a dedicated error type was not enough on its own: UserService.findByApiKey reports an unknown key by throwing rather than by returning nothing, so the commonest 401 in the suite was being answered 503. The lookup is now wrapped in one place that tells the codebase's own INVALID DATA: signal - a caller's mistake - apart from anything else, which is the database being unable to answer. Both directions are pinned by tests.
Let the integration tests run on pull requests from forks
Accept an expected consumption of zero
…-401 A database outage should not be reported as 401 Unauthorized
Bump pricing4ts to ^0.11.1 so Pricing2Yaml 3.1 can be registered
Batching a whole evaluation into one read and one write stopped an evaluation from losing its own limits, but not two requests from losing each other's: both read the same consumed value, both write the same total, and one consumption disappears. The increment is now handed to Mongo as $inc and evaluated against the stored document, so concurrent calls compose. The filter requires every usage level to exist, which keeps validation and the write in one operation instead of leaving a window between them.
Apply expected consumption for all limits in one write
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No description provided.